SideButton Dashboard Knowledge Module
SideButton Dashboard Recordings — Knowledge Module Reference
SideButton Dashboard knowledge module — UI selectors, data model, and page states documenting Recordings.
sidebutton install SideButton Dashboard - Path
- /recordings
- Verified
- 2026-02-21
- Confidence
- 96%
- Role playbooks
- 0
- Pack
- SideButton Dashboard
- Domain
- sidebutton.local
What This Is
The Recordings page captures and manages browser interaction recordings. Users can start recording browser actions (clicks, types, navigations, scrolls), stop recording to save the session, view recorded events with color-coded event types, delete recordings, and convert recordings into reusable workflows (basic conversion or AI-enhanced conversion). Requires the browser extension to be connected. Live recording status is pushed via WebSocket on mount.
URL Patterns
| View | URL | Notes |
|---|---|---|
| Recordings List | /recordings | List of all recordings with start/stop controls |
| Recording Detail | /recordings/{id} | Single recording with event timeline and conversion options |
Page Structure
List View (/recordings)
+--[.header-left: h1 "Recordings" + .item-count badge]--[.header-controls: Start/Stop + Reload]--+
| |
| [.warning-banner — amber — if !browserConnected] |
| [.error-banner — red — if error] |
| |
| [.loading-state — "Loading recordings..." — during fetch] |
| |
| [.recording-list] |
| [.recording-card (button)] |
| [.recording-header: .recording-id (mono) + .event-badge "{n} events"] |
| [.recording-meta: timestamp] |
| ... |
| |
| [.empty-state — when no recordings] |
| [.empty-icon (red circle SVG)] |
| h2 "No Recordings Yet" |
| description text + .hint text |
+--------------------------------------------------------------------------------------------------+
Detail View (/recordings/{id})
+--[.back-btn "Back"]--[.header-actions: Delete / Save as Workflow / Convert with AI]--+
| |
| [.error-banner — red — if error] |
| |
| [.meta-section (grid)] |
| Recording ID (mono) | Recorded (timestamp) | Events (count) |
| |
| [.events-section] |
| [.events-container (monospace)] |
| [.event-item] |
| .event-index "#N" | .event-type (color-coded) | .event-details |
| ... |
| |
| [.raw-section] |
| .raw-json <pre> (max-height 400px, scrollable) |
| |
| [.not-found — "Recording not found." — if ID invalid] |
+---------------------------------------------------------------------------------------+
Key Elements
List View — Header
| Element | Selector | Notes |
|---|---|---|
| Page title | .header-left h1 | Text: "Recordings" |
| Count badge | .header-left .item-count | Shows $recordings.length (e.g., "3") |
| Header controls wrapper | .header-controls | Contains Start/Stop button group and Reload |
| Start Recording button | .header-controls .btn-primary | Has circle SVG icon; disabled when !browserConnected |
| Stop button | .header-controls .btn-stop | Has square SVG icon; visible only while recording |
| Recording status container | .recording-status | Visible only while $recordingStatus.is_recording is true |
| Recording pulse dot | .recording-status .recording-pulse | Red animated dot |
| Recording label | .recording-status .recording-label | Text: "Recording ({eventCount} events)" — updates live via WebSocket |
| Reload button | .header-controls .reload-btn | Has refresh SVG icon; reloads recording list from API |
List View — Banners
| Element | Selector | Notes |
|---|---|---|
| Warning banner | .warning-banner | Amber/orange background; shown when !$mcpStatus.browser_connected; has alert SVG icon |
| Warning text | .warning-banner | Text: "Browser extension not connected. Install and enable the extension to record." |
| Error banner | .error-banner | Red background; shown on API or recording error |
List View — Loading & Empty States
| Element | Selector | Notes |
|---|---|---|
| Loading state | .loading-state | Text: "Loading recordings..."; shown during initial fetch |
| Empty state container | .empty-state | Shown when $recordings.length === 0 and not loading |
| Empty icon | .empty-state .empty-icon | Red circle SVG |
| Empty heading | .empty-state h2 | Text: "No Recordings Yet" |
| Empty description | .empty-state text below h2 | Describes how to start a recording |
| Empty hint | .empty-state .hint | Additional hint text (e.g., extension requirement) |
List View — Recording Cards
| Element | Selector | Notes |
|---|---|---|
| Recording list | .recording-list | Wraps all cards |
| Recording card | .recording-list .recording-card | <button> element; click navigates to /recordings/{id} via navigateToRecordingDetail |
| Card header | .recording-card .recording-header | Contains ID and event badge |
| Recording ID | .recording-card .recording-id | Monospace font; e.g., rec_1708456789_abc123 |
| Event badge | .recording-card .event-badge | Text: "{n} events"; right-aligned in header |
| Card meta | .recording-card .recording-meta | Contains timestamp |
| Timestamp | .recording-card .recording-meta text | Relative time: "just now", "5m ago", "2h ago", or absolute date |
Detail View — Header & Actions
| Element | Selector | Notes |
|---|---|---|
| Back button | .back-btn | Text: "Back"; returns to /recordings |
| Header actions | .header-actions | Contains Delete, Save as Workflow, Convert with AI |
| Delete button | .header-actions button with text "Delete" | Triggers inline confirm UI (NOT native confirm()) |
| Delete confirm text | .confirm-text | Text: "Delete this recording?"; appears inline after clicking Delete |
| Confirm delete button | .btn-danger | Text: "Yes, Delete"; executes deletion |
| Cancel delete button | .header-actions .btn-secondary with text "Cancel" | Dismisses inline confirm |
| Save as Workflow button | .header-actions .btn-secondary with text "Save as Workflow" | Basic YAML conversion; calls convertRecording(id) then navigates to Skills |
| Convert with AI button | .header-actions .btn-primary | Text: "Convert with AI"; purple (#7b1fa2); calls convertRecordingWithLLM(id); disabled when !hasApiKey |
| Converting indicator | .converting | Text: "Converting..."; replaces action buttons during conversion |
| Error banner | .error-banner | Red background; shown on delete or convert error |
Detail View — Meta Section
| Element | Selector | Notes |
|---|---|---|
| Meta grid | .meta-section | CSS grid layout with Recording ID, Recorded, Events fields |
| Recording ID | .meta-section mono text | Full recording ID |
| Recorded timestamp | .meta-section | Full datetime of recording creation |
| Event count | .meta-section | Total number of events in recording |
Detail View — Events
| Element | Selector | Notes |
|---|---|---|
| Events section | .events-section | Container for event timeline |
| Events container | .events-section .events-container | Monospace font; scrollable |
| Event item | .event-item | One row per event |
| Event index | .event-item .event-index | Text: "#N" (1-based) |
| Event type label | .event-item .event-type | Color-coded; see Event Type Colors table |
| Event details | .event-item .event-details | Type-specific details (url, selector, value, direction, amount) |
Event Type Colors
| Type | Color | Hex |
|---|---|---|
| navigate | Blue | #3b82f6 |
| click | Green | #22c55e |
| input | Purple | #a78bfa |
| scroll | Amber | #f59e0b |
| extract | Pink | #ec4899 |
Detail View — Raw JSON & Not Found
| Element | Selector | Notes |
|---|---|---|
| Raw section | .raw-section | Contains raw JSON header and pre block |
| Raw JSON pre | .raw-section .raw-json | <pre> element; max-height 400px; overflow-y auto (scrolls independently) |
| Not found | .not-found | Text: "Recording not found."; shown when ID does not match any recording |
Data Model
Recording
| Field | Type | Notes |
|---|---|---|
| id | string | Recording identifier (e.g., rec_{timestamp}_{random}) |
| events | array | Array of recorded event objects |
| timestamp | datetime | When recording was created |
| eventCount | number | Total number of events; also available as events.length |
Recording Event
| Field | Type | Notes |
|---|---|---|
| type | enum | navigate, click, input, scroll, extract |
| url | string | For navigate events |
| selector | string | For click and input events — CSS selector of target element |
| value | string | For input events — text entered |
| direction | string | For scroll events — up, down, left, right |
| amount | number | For scroll events — pixel amount |
Derived State
| State Variable | Source | Notes |
|---|---|---|
$recordingStatus.is_recording | WebSocket / store | True while a recording session is active |
$recordingStatus.event_count | WebSocket / store | Live event count during active recording |
$mcpStatus.browser_connected | WebSocket / store | True when Chrome extension is connected |
hasApiKey | settings?.llm?.api_key | Derived in detail view; gates "Convert with AI" button |
States
| State | Trigger | Visual Indicator |
|---|---|---|
| Default (with recordings) | Page load with saved recordings | .recording-list with .recording-card items |
| Loading | Initial fetch in progress | .loading-state "Loading recordings..." |
| Empty | No recordings exist | .empty-state with red icon + "No Recordings Yet" |
| Browser disconnected | $mcpStatus.browser_connected is false | .warning-banner shown; Start Recording button disabled |
| Error | API or recording error | .error-banner with red background |
| Recording active | "Start Recording" clicked | .recording-status with .recording-pulse + label; Start replaced by Stop |
| Detail view — normal | Recording ID found | Meta grid + event timeline + raw JSON |
| Detail view — delete confirm | "Delete" clicked (inline) | .confirm-text + .btn-danger + Cancel replace Delete button |
| Detail view — converting | Convert button clicked | .converting "Converting..." replaces action buttons |
| Detail view — not found | Invalid recording ID | .not-found "Recording not found." |
Common Tasks
- Start recording: Click
.btn-primary"Start Recording" (requires browser connected) → interact in browser → events captured live via WebSocket - Stop recording: Click
.btn-stop"Stop" → recording saved → auto-navigates to new recording detail vianavigateToRecordingDetail - View recording: Click
.recording-cardin list → detail view at/recordings/{id} - Delete recording: Detail view → click "Delete" → inline confirm appears (
.confirm-text) → click.btn-danger"Yes, Delete" - Cancel delete: After clicking "Delete", click "Cancel" to dismiss inline confirm without deleting
- Convert to workflow: Detail view → click "Save as Workflow" → basic YAML workflow created → navigates to Skills
- AI-convert to workflow: Detail view → click "Convert with AI" (must have API key) → LLM-optimized workflow → navigates to Skills
- Reload list: Click
.reload-btn→ refreshes recording list from API - Read raw events: Detail view → scroll
.raw-section .raw-jsonpre block (max-height 400px, scrolls independently)
Tips
- Real-time event counter: While recording,
.recording-labelshows live event count updated via WebSocket — no page reload needed - Color-coded events: Each event type has a distinct color (see Event Type Colors table) for quick visual scanning
- AI conversion needs API key: "Convert with AI" button is disabled (
!hasApiKey) if no LLM provider API key is configured in Settings - Relative timestamps: Recording cards show "just now", "5m ago", "2h ago" etc. — refreshes only on page load or Reload button
- WebSocket on mount:
initWebSocket()called on list view mount for live recording status and event count updates - Card is a button:
.recording-cardis a<button>element — use click by ref or CSS selector, not link navigation
Gotchas
- Browser extension required:
.btn-primaryStart Recording is disabled (!browserConnected) without the Chrome extension connected — check sidebar "Browser Connected" indicator - Delete is inline, NOT native confirm: Clicking "Delete" renders
.confirm-text+.btn-danger+ Cancel inline in.header-actions— no browserconfirm()dialog is used; automatable via snapshot/click - Stop navigates automatically: After stopping, the app calls
navigateToRecordingDetail(recording.id)— the list view is not shown again until Back is clicked - Convert with AI disabled silently: If
hasApiKeyis false, the.btn-primarybutton is visually disabled — check Settings → LLM API key before attempting - Converting replaces all buttons: While
.convertingis shown, Delete/Save/Convert buttons are gone — wait for navigation or error before retrying - Raw JSON section scrolls independently:
.raw-jsonhasmax-height: 400px; overflow-y: auto— page scroll does not scroll the JSON block - Not found state on bad ID: Navigating to
/recordings/bad-idrenders.not-foundinline — not a separate route or 404 page - SPA routing:
/recordingsand/recordings/{id}return 404 JSON if accessed directly (server-side) — always navigate via the SPA router